package cn.skycity.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.skycity.common.mapper.SysRoleDeptMapper;
import cn.skycity.common.mapper.SysRoleMapper;
import cn.skycity.common.mapper.SysRoleMenuMapper;
import cn.skycity.common.mapper.SysUserRoleMapper;
import cn.skycity.common.service.ISysRoleMenuService;
import cn.skycity.common.service.ISysRoleService;
import cn.skycity.framework.core.constants.GlobalConstants;
import cn.skycity.framework.core.exception.ServiceException;
import cn.skycity.framework.core.utils.StreamUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.skycity.framework.uaa.pojo.dto.SysRoleBo;
import com.skycity.framework.uaa.pojo.entity.SysRole;
import com.skycity.framework.uaa.pojo.entity.SysRoleDept;
import com.skycity.framework.uaa.pojo.entity.SysRoleMenu;
import com.skycity.framework.uaa.pojo.entity.SysUserRole;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {
    @Resource
    private SysRoleMenuMapper roleMenuMapper;
    @Resource
    private SysUserRoleMapper userRoleMapper;
    @Resource
    private ISysRoleMenuService iSysRoleMenuService;
    @Resource
    private SysRoleDeptMapper sysRoleDeptMapper;
//
//
//    @Override
//    public boolean delete(List<Long> ids) {
//        Optional.ofNullable(ids).orElse(new ArrayList<>()).forEach(id -> {
//            long count = iSysUserRoleService.count(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, id));
//            Assert.isTrue(count <= 0, "该角色已分配用户，无法删除");
//            iSysRoleMenuService.remove(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, id));
////            iSysRolePermissionService.remove(new LambdaQueryWrapper<SysRolePermission>().eq(SysRolePermission::getRoleId, id));
//        });
//        return this.removeByIds(ids);
//    }


    /**
     * 校验角色名称是否唯一
     *
     * @param role 角色信息
     * @return 结果
     */
    @Override
    public boolean checkRoleNameUnique(SysRoleBo role) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::getRoleName, role.getRoleName())
                .ne(ObjectUtil.isNotNull(role.getId()), SysRole::getId, role.getId()));
        return !exist;
    }

    /**
     * 校验角色权限是否唯一
     *
     * @param role 角色信息
     * @return 结果
     */
    @Override
    public boolean checkRoleKeyUnique(SysRoleBo role) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysRole>()
                .eq(SysRole::getRoleKey, role.getRoleKey())
                .ne(ObjectUtil.isNotNull(role.getId()), SysRole::getId, role.getId()));
        return !exist;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateRole(SysRoleBo bo) {
        SysRole role = BeanUtil.toBean(bo, SysRole.class);
        if (GlobalConstants.STAUTS_DISABLED.equals(role.getStatus()) && this.countUserRoleByRoleId(role.getId()) > 0) {
            throw new ServiceException("角色已分配，不能禁用!");
        }
        // 修改角色信息
        baseMapper.updateById(role);
        // 删除角色与菜单关联
        roleMenuMapper.delete(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, role.getId()));
        return insertRoleMenu(bo);
    }

    @Override
    public void cleanOnlineUserByRole(Long roleId) {
        // 如果角色未绑定用户 直接返回
//        Long num = userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
//        if (num == 0) {
//            return;
//        }
//        List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
//        if (CollUtil.isEmpty(keys)) {
//            return;
//        }
//        // 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作
//        keys.parallelStream().forEach(key -> {
//            String token = StringUtils.substringAfterLast(key, ":");
//            // 如果已经过期则跳过
//            if (StpUtil.stpLogic.getTokenActiveTimeoutByToken(token) < -1) {
//                return;
//            }
//            LoginUser loginUser = LoginHelper.getLoginUser(token);
//            if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) {
//                try {
//                    StpUtil.logoutByTokenValue(token);
//                } catch (NotLoginException ignored) {
//                }
//            }
//        });
    }

    /**
     * 新增角色菜单信息
     *
     * @param role 角色对象
     */
    private int insertRoleMenu(SysRoleBo role) {
        int rows = 1;
        // 新增用户与角色管理
        List<SysRoleMenu> list = new ArrayList<>();
        for (Long menuId : role.getMenuIds()) {
            SysRoleMenu rm = new SysRoleMenu();
            rm.setRoleId(role.getId());
            rm.setMenuId(menuId);
            list.add(rm);
        }
        if (list.size() > 0) {
            rows = iSysRoleMenuService.saveBatch(list) ? list.size() : 0;
        }
        return rows;
    }


    /**
     * 通过角色ID查询角色使用数量
     *
     * @param roleId 角色ID
     * @return 结果
     */
    @Override
    public long countUserRoleByRoleId(Long roleId) {
        return userRoleMapper.selectCount(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId));
    }

    @Override
    public int addAuthUser(Long roleId, Long[] userIds) {
        List<SysUserRole> list = StreamUtils.toList(List.of(userIds), userId -> {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            return ur;
        });
        userRoleMapper.insert(list);
        return list.size();
    }

    @Override
    public int revokeAuthUser(Long roleId, Long[] userIds) {
        int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRoleId, roleId)
                .in(SysUserRole::getUserId, Arrays.asList(userIds)));
        if(rows > 0){
            cleanOnlineUserByRole(roleId);
        }
        return rows;
    }

    @Override
    public List<SysRole> selectRoleList() {
        return baseMapper.selectList(new LambdaQueryWrapper<SysRole>().eq(SysRole::getStatus, "1"));
    }


    @Override
    public void checkRoleDataScope(Long id) {
        if (ObjectUtil.isNull(id)) {
            return;
        }
//        List<SysRoleVo> roles = this.selectRoleList(new SysRoleBo(id));
//        if (CollUtil.isEmpty(roles)) {
//            throw new ServiceException("没有权限访问角色数据！");
//        }
    }


    @Override
    public int authDataScope(SysRoleBo bo) {
        SysRole role = BeanUtil.toBean(bo, SysRole.class);
        // 修改角色信息
        baseMapper.updateById(role);
        // 删除角色与部门关联
        sysRoleDeptMapper.delete(new LambdaQueryWrapper<SysRoleDept>().eq(SysRoleDept::getRoleId, role.getId()));
        // 新增角色和部门信息（数据权限）
        return insertRoleDept(bo);
    }


    /**
     * 新增角色部门信息(数据权限)
     *
     * @param role 角色对象
     */
    private int insertRoleDept(SysRoleBo role) {
        int rows = 1;
        List<SysRoleDept> list = new ArrayList<>();
        for (Long deptId : role.getDeptIds()) {
            SysRoleDept rd = new SysRoleDept();
            rd.setRoleId(role.getId());
            rd.setDeptId(deptId);
            list.add(rd);
        }
        if (!list.isEmpty()) {
            rows = sysRoleDeptMapper.insert(list).size();
        }
        return rows;
    }
}
